﻿using Core.SimpleTemp.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Core.SimpleTemp.Application.Common
{
    /// <summary>
    /// 对比实体集合差异
    /// </summary>
    [AutoDi()]
    public class ComPareList
    {
        public ComPareList()
        {

        }
        /// <summary>
        /// 对比两个实体集合的差异
        /// </summary>
        /// <typeparam name="T">集合类型</typeparam>
        /// <param name="listOld">原集合</param>
        /// <param name="listNew">新集合</param>
        ///  <param name="fields">要比较的字段,如果不传该参数就比较所有字段</param>
        /// <returns></returns>
        public ComPareResult<T> CompareList<T>(List<T> listOld, List<T> listNew, List<string> fields = null)
        {
            var listDel = new List<T>();
            var listAdd = new List<T>();
            for (int i = 0; i < listOld.Count(); i++)
            {
                //用listOld每个实体和listNew集合中的所有实体对比差异，此处注意listOld用的是单个实体，listNew用的是集合，对比出的差异即是要删除的
                bool flag = CompareEntity<T>(listOld[i], listNew, fields);
                if (!flag)
                    listDel.Add(listOld[i]);
            }

            for (int i = 0; i < listNew.Count(); i++)
            {
                //用listNew每个实体和listOld集合中的所有实体对比差异，此处注意listNew用的是单个实体，listOld用的是集合，对比出的差异即是要增加的
                bool flag = CompareEntity<T>(listNew[i], listOld, fields);
                if (!flag)
                    listAdd.Add(listNew[i]);
            }
            //返回的结果为要新增的集合 和要删除的集合
            return new ComPareResult<T>() { ListAdd = listAdd, ListDel = listDel };
        }

        /// <summary>
        /// 对比实体是否在集合中存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="oldEntity">被对比实体（A集合的单个实体）</param>
        /// <param name="newEntity">被对比实体集合（B集合）</param>
        /// <param name="fields">要比较的字段,如果不传该参数就比较所有字段</param>
        /// <returns></returns>
        public bool CompareEntity<T>(T oldEntity, List<T> newEntities, List<string> fields = null)
        {
            for (int i = 0; i < newEntities.Count(); i++)
            {
                //B集合的单个实体
                var newEntity = newEntities[i];
                //获取A实体的类型
                Type typeOld = oldEntity.GetType();
                //获取B实体的类型
                Type typeNew = newEntity.GetType();
                //获取A实体类型的属性
                PropertyInfo[] propertyInfos = typeOld.GetProperties();
                foreach (PropertyInfo p in propertyInfos)//遍历A实体的属性
                {
                    //属性名称
                    string name = p.Name;
                    //判断要对比的该属性是否为要对比的字段
                    if (!fields.Contains(name)) { continue; }
                    //读取A实体中指定字段的值
                    string value1 = p.GetValue(oldEntity, null)?.ToString();
                    //读取B实体中指定相同字段的值
                    string value2 = typeNew.GetProperty(name)?.GetValue(newEntity, null)?.ToString();
                    //对比值的差异，并返回结果
                    if (value1 == value2)
                        return true;
                }
            }
            return false;
        }
    }
    /// <summary>
    /// 差异结果类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ComPareResult<T>
    {
        /// <summary>
        /// 新增
        /// </summary>
        public List<T> ListAdd { get; set; }
        /// <summary>
        /// 删除
        /// </summary>
        public List<T> ListDel { get; set; }
    }
}
